vectordotdev / vectordotdev/vector

Support setting IP_TOS (DSCP) on sockets for network sources and sinks

Open
#25,931 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
22.6k
Forks
2.3k
Avg merge
1d 7h
Merged PRs (30d)
146

Description

A note for the community
  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
Use Cases

In shared network infrastructure, it is often necessary to mark traffic with a specific DSCP (Differentiated Services Code Point) value so that network devices can apply QoS policies — prioritizing, shaping, or routing traffic differently based on its class.

Vector's network sources and sinks currently have no way to set the IP_TOS socket option. This means operators must rely on external mechanisms (iptables, tc, LD_PRELOAD shims) to mark Vector's traffic, which is:

  • Fragile — external rules may not survive node reboots, kernel updates, or container restarts.
  • Imprecise — iptables/tc rules match by port or cgroup, not by the actual Vector process intent. They can't distinguish between different sources/sinks that may need different DSCP values.
  • Operationally complex — requires coordination between application teams and network/infra teams, and additional tooling per deployment.

A concrete example: when Vector forwards telemetry data over the network, that traffic may need to be marked as CS2 (DSCP 16, IP_TOS = 0x40) to ensure it gets a medium-priority classification on the network. Today this requires external tooling with elevated privileges, which is a security and operational concern.

Attempted Solutions
  1. iptables / nftables (mangle table) — mark traffic by destination port or cgroup:

    iptables -t mangle -A OUTPUT -p tcp --dport 9092 -j DSCP --set-dscp-class CS2
    

    Works, but requires NET_ADMIN capability, is not portable across environments, and cannot differentiate between multiple sinks of the same type on different ports.

  2. tc with skbedit — similar to iptables, same limitations.

  3. LD_PRELOAD shim — a small C library that intercepts socket() and calls setsockopt(fd, IPPROTO_IP, IP_TOS, ...):

    int socket(int domain, int type, int protocol) {
        int fd = real_socket(domain, type, protocol);
        if (fd >= 0) {
            int tos = 0x40;
            setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
        }
        return fd;
    }
    

    Works but applies to ALL sockets indiscriminately — cannot target specific sources/sinks.

  4. External proxy — routing traffic through a proxy that sets TOS. Adds latency, complexity, and an additional failure point.

None of these solutions allow per-source or per-sink TOS configuration, which is what we need.

Proposal

Add an ip_tos (or dscp) configuration option to network-based sources and sinks, allowing operators to set the IP_TOS socket option on outbound/inbound connections.

Suggested config:

[sinks.my_sink]
type = "http"
# ...
ip_tos = 64          # integer: raw IP_TOS value (0-255)
# or
# dscp = "CS2"       # string: DSCP class name (CS0-CS7, AF11-AF43, EF)
[sources.my_source]
type = "socket"
# ...
ip_tos = 64

The value would be applied via setsockopt(fd, IPPROTO_IP, IP_TOS, &value, sizeof(value)) on each socket created by the source/sink.

Technical feasibility: Vector already depends on the socket2 crate, which provides Socket::set_tos() and Socket::tos() methods. This means the underlying capability is already available — no new dependencies needed, just wiring up the config option to the existing socket2 API.

Scope considerations:

  • The option could initially be added to the most network-heavy components and extended to others over time.
  • A global ip_tos setting (in the top-level config or [network] section) could also be useful as a catch-all, with per-source/sink overrides.
  • Both integer (raw IP_TOS byte) and string (DSCP class name) formats would be ergonomic, but integer-only for an initial implementation would be sufficient.
References
  • socket2 crate: docs.rs/socket2
  • RFC 2474 — Definition of the Differentiated Services Field (DS Field)
  • RFC 791 — Type of Service field definition (original, superseded by RFC 2474)
Version

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the network sources and sinks that create sockets, then read the existing socket2 integration and its set_tos() API. Define the initial component scope and configuration shape before wiring the option to socket creation. Done means the selected components can apply a per-source or per-sink IP_TOS value without adding a dependency.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, networking
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.