]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Support DSCP marking towards downstream server
authorOliver Chen <oliver.chen@nokia-sbell.com>
Wed, 16 Apr 2025 03:36:05 +0000 (03:36 +0000)
committerOliver Chen <oliver.chen@nokia-sbell.com>
Wed, 16 Apr 2025 03:36:05 +0000 (03:36 +0000)
pdns/dnsdistdist/dnsdist-backend.cc
pdns/dnsdistdist/dnsdist-configuration-yaml.cc
pdns/dnsdistdist/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist-rust-lib/rust/src/lib.rs
pdns/dnsdistdist/dnsdist-settings-definitions.yml
pdns/dnsdistdist/dnsdist-tcp-downstream.cc
pdns/dnsdistdist/dnsdist.hh
pdns/dnsdistdist/docs/reference/config.rst
pdns/dnsdistdist/docs/reference/yaml-settings.rst
pdns/misc.cc
pdns/misc.hh

index 31e9d254cd5dd06d3627121ec91fb5afe4e53f3a..d1f144ee2267897cda82025337174968cea94c4e 100644 (file)
@@ -140,6 +140,7 @@ bool DownstreamState::reconnect(bool initialAttempt)
     }
 
     try {
+      setDscp(fd, d_config.remote.sin4.sin_family, d_config.dscp);
       SConnect(fd, d_config.remote);
       if (sockets.size() > 1) {
         (*mplexer.lock())->addReadFD(fd, [](int, boost::any) {});
index 459552af327eb5da9ac3ee62199504db8906b7c4..475a75660c61b3b45c66f57a245aa88690d9fd6d 100644 (file)
@@ -507,6 +507,8 @@ static std::shared_ptr<DownstreamState> createBackendFromConfiguration(const dns
     dnsdist::ServiceDiscovery::addUpgradeableServer(downstream, autoUpgradeConf.interval, std::string(autoUpgradeConf.pool), autoUpgradeConf.doh_key, autoUpgradeConf.keep);
   }
 
+  backendConfig.dscp = config.dscp;
+
   return downstream;
 }
 
index 3504cbd6a408277776f5cf0f6a5b2ed2ebeb21cc..f52ae0cfe28ba400eca88962cd4538d40cecd1e0 100644 (file)
@@ -503,6 +503,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
                          getOptionalValue<bool>(vars, "enableRenegotiation", config.d_tlsParams.d_enableRenegotiation);
                          getOptionalValue<bool>(vars, "ktls", config.d_tlsParams.d_ktls);
                          getOptionalValue<std::string>(vars, "subjectName", config.d_tlsSubjectName);
+                         getOptionalIntegerValue("newServer", vars, "dscp", config.dscp);
 
                          if (vars->count("keyLogFile") > 0) {
 #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
index be2411ba96a4cbe85d9ec3f6e702cbd210f9e39f..cdab005007c3a23e51bff08ed5d04b66e22f17f3 100644 (file)
@@ -1844,6 +1844,8 @@ mod dnsdistsettings {
         cpus: String,
         #[serde(default, skip_serializing_if = "crate::is_default")]
         xsk: String,
+        #[serde(default, skip_serializing_if = "crate::is_default")]
+        dscp: u8,
     }
 
     #[derive(Deserialize, Serialize, Debug, PartialEq)]
index a00387a0e148f25447f4654fd203fca61a65c1eb..fd1de4234f413862988003cff86e591d5013f5f4 100644 (file)
@@ -1425,6 +1425,10 @@ backend:
       type: "String"
       default: ""
       description: "The name of an XSK sockets map to attach to this frontend, if any"
+    - name: "dscp"
+      type: "u8"
+      default: 0
+      description: "The DSCP marking value to be applied. Range 0-63. Default is 0 which means no action for DSCP marking."
 
 tuning:
   description: "Tuning settings"
index 5c1335438b5feb3c14161a27d120d9734604d8e1..1c91bba13753a623b9d079c3230ad78245f68a12 100644 (file)
@@ -81,6 +81,7 @@ bool ConnectionToBackend::reconnect()
          the other end to acknowledge our initial packet before we could
          send the rest. */
       setTCPNoDelay(socket.getHandle());
+      setDscp(socket.getHandle(), d_ds->d_config.remote.sin4.sin_family, d_ds->d_config.dscp);
 
 #ifdef SO_BINDTODEVICE
       if (!d_ds->d_config.sourceItfName.empty()) {
index 56ee6e8042de4256f36aff78765f1fe83ee8f64b..866c8787257c06da09d16486d6f33ae4a72507ff 100644 (file)
@@ -592,6 +592,7 @@ struct DownstreamState : public std::enable_shared_from_this<DownstreamState>
     uint8_t maxCheckFailures{1};
     uint8_t minRiseSuccesses{1};
     uint8_t udpTimeout{0};
+    uint8_t dscp{0};
     Availability availability{Availability::Auto};
     bool d_tlsSubjectIsAddr{false};
     bool mustResolve{false};
index 870129bc48dcb39a3bebcced7c66efaed3ce3e41..b8f8eab9d95a0c8b1693e7486e5a07d0676a3469 100644 (file)
@@ -759,6 +759,7 @@ Servers
     ``xskSockets``                            ``array``            "An array of :class:`XskSocket` objects to enable ``XSK`` / ``AF_XDP`` support for this backend. See :doc:`../advanced/xsk` for more information."
     ``MACAddr``                              ``str``               "When the ``xskSocket`` option is set, this parameter can be used to specify the destination MAC address to use to reach the backend. If this options is not specified, dnsdist will try to get it from the IP of the backend by looking into the system's MAC address table, but it will fail if the corresponding MAC address is not present."
     ``keyLogFile``                           ``str``               "Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. Note that this feature requires OpenSSL >= 1.1.1."
+    ``dscp``                                 ``number``            "The DSCP marking value to be applied. Range 0-63. Default is 0 which means no action for DSCP marking."
 
 .. function:: getServer(index) -> Server
 
index 8876dd6075e881cd1627c680005427eee4b81e53..c594c491c14b55d87bc24fe3d522a05cea5a2e5f 100644 (file)
@@ -101,6 +101,7 @@ Generic settings for backends
 - **mac_address**: String ``("")`` - When the ``xsk`` option is set, this parameter can be used to specify the destination MAC address to use to reach the backend. If this options is not specified, dnsdist will try to get it from the IP of the backend by looking into the system's MAC address table, but it will fail if the corresponding MAC address is not present
 - **cpus**: String ``("")`` - Set the CPU affinity for this thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the ``pthread_setaffinity_np()`` function
 - **xsk**: String ``("")`` - The name of an XSK sockets map to attach to this frontend, if any
+- **dscp**: Unsigned integer ``(0)`` - The DSCP marking value to be applied. Range 0-63. Default is 0 which means no action for DSCP marking.
 
 
 .. _yaml-settings-BindConfiguration:
index a64f00a5feb0f2810aaaf02fc8c68be03053faf8..26335e9203371ba73f96c09453d3cd212eee2593 100644 (file)
@@ -1082,6 +1082,36 @@ bool setReuseAddr(int sock)
   return true;
 }
 
+void setDscp(int sock, unsigned short family, uint8_t dscp)
+{
+  int val;
+  unsigned int len;
+
+  if (dscp == 0 || dscp > 63) {
+    // No DSCP marking
+    return;
+  }
+
+  if (family == AF_INET) {
+    if (getsockopt(sock, IPPROTO_IP, IP_TOS, &val, &len)<0) {
+      throw std::runtime_error(string("Set DSCP failed: ")+stringerror());
+    }
+    val = (dscp<<2) | (val&0x3);
+    if (setsockopt(sock, IPPROTO_IP, IP_TOS, &val, sizeof(val))<0) {
+      throw std::runtime_error(string("Set DSCP failed: ")+stringerror());
+    }
+  }
+  else if (family == AF_INET6) {
+    if (getsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &val, &len)<0) {
+      throw std::runtime_error(string("Set DSCP failed: ")+stringerror());
+    }
+    val = (dscp<<2) | (val&0x3);
+    if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val))<0) {
+      throw std::runtime_error(string("Set DSCP failed: ")+stringerror());
+    }
+  }
+}
+
 bool isNonBlocking(int sock)
 {
   int flags=fcntl(sock,F_GETFL,0);
index 6129d37664daa44a75a582e0ff3c7d24195f8c88..6b1c70cf2401b604f7d62a6c35d6033b8e16d351 100644 (file)
@@ -593,6 +593,8 @@ bool setSocketTimestamps(int fd);
 //! Sets the socket into blocking mode.
 bool setBlocking( int sock );
 
+void setDscp(int sock, unsigned short family, uint8_t dscp);
+
 //! Sets the socket into non-blocking mode.
 bool setNonBlocking( int sock );
 bool setTCPNoDelay(int sock);