}
// create but don't connect the socket in client or check-config modes
- auto ret = std::make_shared<DownstreamState>(serverAddr, sourceAddr, sourceItf, sourceItfName, numberOfSockets, !(client || configCheck));
+ auto ret = std::make_shared<DownstreamState>(serverAddr, sourceAddr, sourceItf, sourceItfName);
if (!(client || configCheck)) {
infolog("Added downstream server %s", serverAddr.toStringWithPort());
}
if (!ret->isTCPOnly() && !(client || configCheck)) {
ret->idStates.resize(g_maxOutstanding);
+ if (!IsAnyAddress(ret->remote)) {
+ ret->connectUDPSockets(numberOfSockets);
+ }
}
/* this needs to be done _AFTER_ the order has been set,
luaCtx.writeFunction("getServer", [client](boost::variant<unsigned int, std::string> i) {
if (client) {
- return std::make_shared<DownstreamState>(ComboAddress(), ComboAddress(), 0, std::string(), 1, false);
+ return std::make_shared<DownstreamState>(ComboAddress());
}
auto states = g_dstates.getCopy();
if (auto str = boost::get<std::string>(&i)) {
{
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, const std::string& sourceItfName, size_t numberOfSockets, bool connect);
- DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, std::string(), 1, true) {}
+ DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf, const std::string& sourceItfName);
+ DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, std::string()) {}
~DownstreamState();
+ void connectUDPSockets(size_t numberOfSockets);
stat_t sendErrors{0};
stat_t outstanding{0};
}
}
-DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, const std::string& sourceItfName_, size_t numberOfSockets, bool connect): remote(remote_), sourceAddr(sourceAddr_), sourceItfName(sourceItfName_), name(remote_.toStringWithPort()), nameWithAddr(remote_.toStringWithPort()), sourceItf(sourceItf_)
+DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, const std::string& sourceItfName_): remote(remote_), sourceAddr(sourceAddr_), sourceItfName(sourceItfName_), name(remote_.toStringWithPort()), nameWithAddr(remote_.toStringWithPort()), sourceItf(sourceItf_)
{
id = getUniqueID();
threadStarted.clear();
- *(mplexer.lock()) = std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent());
+ sw.start();
+}
+void DownstreamState::connectUDPSockets(size_t numberOfSockets)
+{
sockets.resize(numberOfSockets);
+
+ if (sockets.size() > 1) {
+ *(mplexer.lock()) = std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent());
+ }
+
for (auto& fd : sockets) {
fd = -1;
}
- if (connect && !IsAnyAddress(remote)) {
- reconnect();
- sw.start();
- }
+ reconnect();
}
DownstreamState::~DownstreamState()
-- "address@interface", e.g. "192.0.2.2@eth0"
addXPF=NUM, -- Add the client's IP address and port to the query, along with the original destination address and port,
-- using the experimental XPF record from `draft-bellis-dnsop-xpf <https://datatracker.ietf.org/doc/draft-bellis-dnsop-xpf/>`_ and the specified option code. Default is disabled (0)
- sockets=NUM, -- Number of sockets (and thus source ports) used toward the backend server, defaults to a single one. Note that for backends which are multithreaded, this setting will have an effect on the number of cores that will be used to process traffic from dnsdist. For example you may want to set 'sockets' to a number somewhat higher than the number of worker threads configured in the backend, particularly if the Linux kernel is being used to distribute traffic to multiple threads listening on the same socket (via `reuseport`).
+ sockets=NUM, -- Number of UDP sockets (and thus source ports) used toward the backend server, defaults to a single one. Note that for backends which are multithreaded, this setting will have an effect on the number of cores that will be used to process traffic from dnsdist. For example you may want to set 'sockets' to a number somewhat higher than the number of worker threads configured in the backend, particularly if the Linux kernel is being used to distribute traffic to multiple threads listening on the same socket (via `reuseport`).
disableZeroScope=BOOL, -- Disable the EDNS Client Subnet 'zero scope' feature, which does a cache lookup for an answer valid for all subnets (ECS scope of 0) before adding ECS information to the query and doing the regular lookup. This requires the ``parseECS`` option of the corresponding cache to be set to true
rise=NUM, -- Require NUM consecutive successful checks before declaring the backend up, default: 1
useProxyProtocol=BOOL, -- Add a proxy protocol header to the query, passing along the client's IP address and port along with the original destination address and port. Default is disabled.
}
ServerPolicy::NumberedServerVector servers;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
servers.at(idx - 1).second->setUp();
/* we need to have a weight of at least 1000 to get an optimal repartition with the consistent hashing algo */
servers.at(idx - 1).second->setWeight(1000);
ServerPolicy pol{"firstAvailable", firstAvailable, false};
ServerPolicy::NumberedServerVector servers;
- servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53")) });
/* servers start as 'down' */
auto server = pol.getSelectedBackend(servers, dq);
BOOST_CHECK(server != nullptr);
/* add a second server, we should still get the first one */
- servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53")) });
server = pol.getSelectedBackend(servers, dq);
BOOST_REQUIRE(server != nullptr);
BOOST_CHECK(server == servers.at(0).second);
ServerPolicy pol{"firstAvailable", firstAvailable, false};
ServerPolicy::NumberedServerVector servers;
- servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53"), ComboAddress(), 0, std::string(), 1, false) });
- servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53")) });
+ servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53")) });
/* Second server has a higher order, so most queries should be routed to the first (remember that
we need to keep them ordered!).
However the first server has a QPS limit at 10 qps, so any query above that should be routed
auto server = pol.getSelectedBackend(servers, dq);
BOOST_CHECK(server == nullptr);
- servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53")) });
/* servers start as 'down' but the RR policy returns a server unless g_roundrobinFailOnNoServer is set */
g_roundrobinFailOnNoServer = true;
BOOST_CHECK(server != nullptr);
/* add a second server, we should get the first one then the second one */
- servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53")) });
servers.at(1).second->setUp();
server = pol.getSelectedBackend(servers, dq);
BOOST_REQUIRE(server != nullptr);
ServerPolicy pol{"leastOutstanding", leastOutstanding, false};
ServerPolicy::NumberedServerVector servers;
- servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 1, std::make_shared<DownstreamState>(ComboAddress("192.0.2.1:53")) });
/* servers start as 'down' */
auto server = pol.getSelectedBackend(servers, dq);
BOOST_CHECK(server != nullptr);
/* add a second server, we should still get the first one */
- servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ 2, std::make_shared<DownstreamState>(ComboAddress("192.0.2.2:53")) });
server = pol.getSelectedBackend(servers, dq);
BOOST_REQUIRE(server != nullptr);
BOOST_CHECK(server == servers.at(0).second);
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
}
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
}
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
/* we need to have a weight of at least 1000 to get an optimal repartition with the consistent hashing algo */
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
}
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
}
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
}
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
}
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
- servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53"), ComboAddress(), 0, std::string(), 1, false) });
+ servers.push_back({ idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")) });
serversMap[servers.at(idx - 1).second] = 0;
servers.at(idx - 1).second->setUp();
/* we need to have a weight of at least 1000 to get an optimal repartition with the consistent hashing algo */
s_responses[counter] = {query, response};
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
response.resize(11);
s_responses[counter] = {query, response};
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
struct timeval now;
gettimeofday(&now, nullptr);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
backend->d_tlsSubjectName = "backend.powerdns.com";
backend->d_dohPath = "/dns-query";
const uint8_t sizeBytes[] = { static_cast<uint8_t>(querySize / 256), static_cast<uint8_t>(querySize % 256) };
query.insert(query.begin(), sizeBytes, sizeBytes + 2);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
{
ConnectionInfo connInfo(&localCS);
connInfo.remote = getBackendAddress("84", 4242);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
/* enable out-of-order on the backend side as well */
backend->d_maxInFlightQueriesPerConn = 65536;
s_readBuffer.insert(s_readBuffer.end(), queries.at(1).begin(), queries.at(1).end());
s_readBuffer.insert(s_readBuffer.end(), queries.at(2).begin(), queries.at(2).end());
- auto proxyEnabledBackend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto proxyEnabledBackend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
proxyEnabledBackend->d_tlsCtx = tlsCtx;
/* enable out-of-order on the backend side as well */
proxyEnabledBackend->d_maxInFlightQueriesPerConn = 65536;
s_readBuffer.insert(s_readBuffer.end(), queries.at(1).begin(), queries.at(1).end());
s_readBuffer.insert(s_readBuffer.end(), queries.at(2).begin(), queries.at(2).end());
- auto proxyEnabledBackend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto proxyEnabledBackend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
proxyEnabledBackend->d_tlsCtx = tlsCtx;
/* enable out-of-order on the backend side as well */
proxyEnabledBackend->d_maxInFlightQueriesPerConn = 65536;
expectedWriteBuffer.insert(expectedWriteBuffer.end(), responses.at(4).begin(), responses.at(4).end());
expectedWriteBuffer.insert(expectedWriteBuffer.end(), responses.at(3).begin(), responses.at(3).end());
- auto backend1 = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend1 = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend1->d_tlsCtx = tlsCtx;
/* only two queries in flight! */
backend1->d_maxInFlightQueriesPerConn = 2;
auto tlsCtx = std::make_shared<MockupTLSCtx>();
localCS.tlsFrontend = std::make_shared<TLSFrontend>(tlsCtx);
- auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53), ComboAddress("0.0.0.0:0"), 0, std::string(), 1, false);
+ auto backend = std::make_shared<DownstreamState>(getBackendAddress("42", 53));
backend->d_tlsCtx = tlsCtx;
/* shorter than the client one */
backend->tcpRecvTimeout = 1;