//go:build linux || openbsd || freebsd /* SPDX-License-Identifier: MIT * * Copyright (C) 2017-2025 WireGuard LLC. All Rights Reserved. */ package conn import ( "runtime" "syscall" "golang.org/x/sys/unix" ) var fwmarkIoctl int func init() { switch runtime.GOOS { case "linux", "android": fwmarkIoctl = 36 /* unix.SO_MARK */ case "freebsd": fwmarkIoctl = 0x1015 /* unix.SO_USER_COOKIE */ case "openbsd": fwmarkIoctl = 0x1021 /* unix.SO_RTABLE */ } } func (s *StdNetBind) SetMark(mark uint32) error { var operr error if fwmarkIoctl == 0 { return nil } if s.ipv4 != nil { fd, err := s.ipv4.SyscallConn() if err != nil { return err } err = fd.Control(func(fd uintptr) { operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark)) }) if err == nil { err = operr } if err != nil { return err } } if s.ipv6 != nil { fd, err := s.ipv6.SyscallConn() if err != nil { return err } err = fd.Control(func(fd uintptr) { operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark)) }) if err == nil { err = operr } if err != nil { return err } } return nil } func (b *BindStream) SetMark(mark uint32) error { b.closeConnections() ctrl := b.dialer.Control b.dialer.Control = func(network, address string, c syscall.RawConn) error { if ctrl != nil { if err := ctrl(network, address, c); err != nil { return err } } err := c.Control(func(fd uintptr) { unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark)) }) return err } ctrl = b.listenConfig.Control b.listenConfig.Control = func(network, address string, c syscall.RawConn) error { if ctrl != nil { if err := ctrl(network, address, c); err != nil { return err } } err := c.Control(func(fd uintptr) { unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark)) }) return err } return b.openConnections() }